#ifndef JTABLE_H
#define JTABLE_H

#include <wx/dataview.h>
#include <map>
#include <vector>
#include <wx/variant.h>
#include <memory>

class JTable;

typedef std::shared_ptr<JTable> JTablePtr;

class JTable
{
public:
    typedef std::vector<std::wstring> StringArray;
    typedef std::map<std::wstring,unsigned int> StringIntMap;
    typedef std::vector<wxVariant> RowData;
    typedef std::vector<RowData*> TableData;
protected:
    StringArray     m_keys;
    StringIntMap    m_keyMap;
    TableData       m_tableData;
    JTable();

public:
    virtual ~JTable();
    static JTablePtr NewTable();
public:
    inline std::wstring getColumnName(unsigned int column)const
    {return m_keys[column];}
    inline unsigned int getIdxFromName(const std::wstring & colName)const
    {auto ptr=m_keyMap.find(colName);return ptr==m_keyMap.end()?-1:ptr->second;}

    unsigned int AppendColumn(const std::wstring & colName);
    unsigned int InsertColumn(const std::wstring & colName,unsigned int pos);
    unsigned int RemoveColumn(const std::wstring & colName);
    unsigned int RemoveColumn(unsigned int  colIdx);
    void RemoveAllRows();
    void RemoveAllColumns();
    void clear();
    inline size_t GetRowCount()const{return m_tableData.size();}
    inline size_t GetColumnCount()const {return m_keys.size();}
    unsigned int SetRowCount(unsigned int newCount);
    unsigned int InsertRow(unsigned int pos);
    unsigned int RemoveRow(unsigned int pos);
    unsigned int AppendRow();
    inline RowData* GetRowData(unsigned int row)
    {return m_tableData[row];}
    inline const RowData* GetRowData(unsigned int row)const
    {return m_tableData[row];}
    inline void row_reserve(size_t nn)
    {m_tableData.reserve(nn);}


    inline void setCell(unsigned int row, unsigned int column, const wxVariant &data)
    {(*this->m_tableData[row])[column]=data;}
    inline wxVariant & getCell(unsigned int row, unsigned int column)
    { return (*this->m_tableData[row])[column];}
    inline const wxVariant & getCell(unsigned int row, unsigned int column)const
    { return (*this->m_tableData[row])[column];}

    inline void setCell(unsigned int row, const std::wstring &column, const wxVariant &data)
    {
        (*m_tableData[row])[m_keyMap[column]]=data;
    }

    inline wxVariant & getCell(unsigned int row, const std::wstring &column)
    {
        return (*m_tableData[row])[m_keyMap[column]];
    }

    inline const wxVariant & getCell(unsigned int row, const std::wstring &column) const
    {
        return (*m_tableData[row])[const_cast<StringIntMap&>(m_keyMap)[column]];
    }


};

#endif // JTABLE_H
